module utils.VideoCollect;

import std.conv : to;
import std.regex : ctRegex, matchFirst, matchAll;
import std.digest : toHexString;
import std.digest.md : md5Of;
import std.typecons : Tuple, tuple;

import libdominator;

import model.Teleplay;
import model.TeleplayVlink;
import model.Movie;
import model.MovieVlink;
import model.Animation;
import model.AnimationVlink;

import utils.CommonTool : CommonTool;

// import std.stdio;

class VideoCollect
{
    /** 
     * 获取电视剧视频信息（含基本信息及播放链接）
     * Params:
     *   url    string    视频url地址
     * Returns: Tuple!(TeleplayDtoFromCreate, TeleplayVlinkDtoFromCreate[])
     */
    public static Tuple!(TeleplayDtoFromCreate, TeleplayVlinkDtoFromCreate[]) getTeleplayInfo (
        string url)
    {
        TeleplayDtoFromCreate teleplay = null;
        TeleplayVlinkDtoFromCreate[] teleplayLinkList = [];

        string htmlStr = CommonTool.getHtml(url);
        if (htmlStr is null || htmlStr == "")
        {
            return tuple(teleplay, teleplayLinkList);
        }

        Dominator dom = new Dominator(htmlStr);

        Node[] nameNodes = dom.filterDom("*{class:stui-content__detail}.h1");
        if (nameNodes.length == 0)
        {
            return tuple(teleplay, teleplayLinkList);
        }
        string name = dom.getInner(nameNodes[0]);
        // writeln(name);

        string teleplayId = to!string(toHexString(md5Of(name)));

        Node[] infosNodes = dom.filterDom("*{class:stui-content__detail}.p");
        if (infosNodes.length == 0)
        {
            return tuple(teleplay, teleplayLinkList);
        }
        auto rexActors = ctRegex!(`<a href=".*?" target="_blank">(.*?)</a>&nbsp;`);
        auto actorsMatchs = matchAll(dom.getInner(infosNodes[0]), rexActors);
        string actors = "";
        if (actorsMatchs.empty)
        {
            actors = "未知";
        }
        else
        {
            foreach (m; actorsMatchs)
            {
                actors ~= (m[1] ~ " ");
            }
        }
        // writeln(actors);

        auto rexDirector = ctRegex!(`<a href=".*?" target="_blank">(.*?)</a>&nbsp;`);
        auto directorMatchs = matchAll(dom.getInner(infosNodes[1]), rexDirector);
        string directors = "";
        if (directorMatchs.empty)
        {
            directors = "未知";
        }
        else
        {
            foreach (m; directorMatchs)
            {
                directors ~= (m[1] ~ " ");
            }
        }
        // writeln(directors);

        auto rexCate = ctRegex!(`类型：</span>(.*?)<span`);
        auto cateMatch = matchFirst(dom.getInner(infosNodes[2]), rexCate);
        string cate = "";
        if (cateMatch.empty)
        {
            cate = "未知";
        }
        cate = cateMatch[1];
        // writeln(cate);

        auto rexRegion = ctRegex!(`地区：</span>(.*?)<span`);
        auto regionMatch = matchFirst(dom.getInner(infosNodes[2]), rexRegion);
        string region = "";
        if (regionMatch.empty)
        {
            region = "未知";
        }
        region = regionMatch[1];
        // writeln(region);

        auto rexYear = ctRegex!(`年份：</span>(.*?)$`);
        // auto rexYear = ctRegex!(`年份：</span>(\d+)`);
        auto yearMatch = matchFirst(dom.getInner(infosNodes[2]), rexYear);
        uint year;
        if (yearMatch.empty)
        {
            year = 0;
        }
        year = to!uint(yearMatch[1]);
        // writeln(year);

        auto rexIntro = ctRegex!(`简介：</span><span class="detail-sketch">(.*?)</span>`);
        auto introMatch = matchFirst(dom.getInner(infosNodes[4]), rexIntro);
        string intro = "";
        if (introMatch.empty)
        {
            intro = "未知";
        }
        intro = introMatch[1];
        // writeln(intro);

        auto imgAttrs = dom.filterDom("img{class:lazyload}")[0].getAttributes();
        string img = "";
        if (imgAttrs.length == 0)
        {
            img = "";
        }
        else
        {
            img = imgAttrs[2].values[0];
        }

        teleplay = new TeleplayDtoFromCreate(teleplayId, name, url, cate, region, year, actors, directors, intro, img, "暂无");

        Node[] linkNodes = dom.filterDom("ul{class:stui-content__playlist}");
        auto rexlinkInfos = ctRegex!(`<a href="(.*?)">(.*?)</a>`);
        auto linkInfosMatchs = matchAll(dom.getInner(linkNodes[0]), rexlinkInfos);
        if (linkInfosMatchs.empty)
        {
            return tuple(teleplay, teleplayLinkList);
        }
        foreach (link; linkInfosMatchs)
        {
            teleplayLinkList ~= new TeleplayVlinkDtoFromCreate(
                teleplayId,
                link[2],
                ("https://www.hmmgy.com" ~ link[1]));
        }

        return tuple(teleplay, teleplayLinkList);
    }

    /** 
     * 获取电影视频信息（含基本信息及播放链接）
     * Params:
     *   url    string    视频url地址
     * Returns: Tuple!(MovieDtoFromCreate, MovieVlinkDtoFromCreate[])
     */
    public static Tuple!(MovieDtoFromCreate, MovieVlinkDtoFromCreate[]) getMovieInfo (
        string url)
    {
        MovieDtoFromCreate movie = null;
        MovieVlinkDtoFromCreate[] movieLinkList = [];

        string htmlStr = CommonTool.getHtml(url);
        if (htmlStr is null || htmlStr == "")
        {
            return tuple(movie, movieLinkList);
        }

        Dominator dom = new Dominator(htmlStr);

        Node[] nameNodes = dom.filterDom("*{class:stui-content__detail}.h1");
        if (nameNodes.length == 0)
        {
            return tuple(movie, movieLinkList);
        }
        string name = dom.getInner(nameNodes[0]);
        // writeln(name);

        string movieId = to!string(toHexString(md5Of(name)));

        Node[] infosNodes = dom.filterDom("*{class:stui-content__detail}.p");
        if (infosNodes.length == 0)
        {
            return tuple(movie, movieLinkList);
        }

        auto rexActors = ctRegex!(`<a href=".*?" target="_blank">(.*?)</a>&nbsp;`);
        auto actorsMatchs = matchAll(dom.getInner(infosNodes[0]), rexActors);
        string actors = "";
        if (actorsMatchs.empty)
        {
            actors = "未知";
        }
        else
        {
            foreach (m; actorsMatchs)
            {
                actors ~= (m[1] ~ " ");
            }
        }
        // writeln(actors);

        auto rexDirector = ctRegex!(`<a href=".*?" target="_blank">(.*?)</a>&nbsp;`);
        auto directorMatchs = matchAll(dom.getInner(infosNodes[1]), rexDirector);
        string directors = "";
        if (directorMatchs.empty)
        {
            directors = "未知";
        }
        else
        {
            foreach (m; directorMatchs)
            {
                directors ~= (m[1] ~ " ");
            }
        }
        // writeln(directors);

        auto rexCate = ctRegex!(`类型：</span>(.*?)<span`);
        auto cateMatch = matchFirst(dom.getInner(infosNodes[2]), rexCate);
        string cate = "";
        if (cateMatch.empty)
        {
            cate = "未知";
        }
        cate = cateMatch[1];
        // writeln(cate);

        auto rexRegion = ctRegex!(`地区：</span>(.*?)<span`);
        auto regionMatch = matchFirst(dom.getInner(infosNodes[2]), rexRegion);
        string region = "";
        if (regionMatch.empty)
        {
            region = "未知";
        }
        region = regionMatch[1];
        // writeln(region);

        auto rexYear = ctRegex!(`年份：</span>(.*?)$`);
        // auto rexYear = ctRegex!(`年份：</span>(\d+)`);
        auto yearMatch = matchFirst(dom.getInner(infosNodes[2]), rexYear);
        uint year;
        if (yearMatch.empty)
        {
            year = 0;
        }
        year = to!uint(yearMatch[1]);
        // writeln(year);

        auto rexIntro = ctRegex!(`简介：</span><span class="detail-sketch">(.*?)</span>`);
        auto introMatch = matchFirst(dom.getInner(infosNodes[4]), rexIntro);
        string intro = "";
        if (introMatch.empty)
        {
            intro = "未知";
        }
        intro = introMatch[1];
        // writeln(intro);

        auto imgAttrs = dom.filterDom("img{class:lazyload}")[0].getAttributes();
        string img = "";
        if (imgAttrs.length == 0)
        {
            img = "";
        }
        else
        {
            img = imgAttrs[2].values[0];
        }

        movie = new MovieDtoFromCreate(movieId, name, url, cate, region, year, actors, directors, intro, img, "暂无");

        Node[] linkNodes = dom.filterDom("ul{class:stui-content__playlist}");
        auto rexlinkInfos = ctRegex!(`<a href="(.*?)">(.*?)</a>`);
        auto linkInfosMatchs = matchAll(dom.getInner(linkNodes[0]), rexlinkInfos);
        if (linkInfosMatchs.empty)
        {
            return tuple(movie, movieLinkList);
        }
        foreach (link; linkInfosMatchs)
        {
            movieLinkList ~= new MovieVlinkDtoFromCreate(
                movieId,
                link[2],
                ("https://www.hmmgy.com" ~ link[1]));
        }

        return tuple(movie, movieLinkList);
    }

    /** 
     * 获取动漫视频信息（含基本信息及播放链接）
     * Params:
     *   url    string    视频url地址
     * Returns: Tuple!(AnimationDtoFromCreate, AnimationVlinkDtoFromCreate[])
     */
    public static Tuple!(AnimationDtoFromCreate, AnimationVlinkDtoFromCreate[]) getAnimationInfo (
        string url)
    {
        AnimationDtoFromCreate animation = null;
        AnimationVlinkDtoFromCreate[] animationLinkList = [];

        string htmlStr = CommonTool.getHtml(url);
        if (htmlStr is null || htmlStr == "")
        {
            return tuple(animation, animationLinkList);
        }

        Dominator dom = new Dominator(htmlStr);

        Node[] nameNodes = dom.filterDom("*{class:stui-content__detail}.h1");
        if (nameNodes.length == 0)
        {
            return tuple(animation, animationLinkList);
        }
        string name = dom.getInner(nameNodes[0]);
        // writeln(name);

        string animationId = to!string(toHexString(md5Of(name)));

        Node[] infosNodes = dom.filterDom("*{class:stui-content__detail}.p");
        if (infosNodes.length == 0)
        {
            return tuple(animation, animationLinkList);
        }
        auto rexActors = ctRegex!(`<a href=".*?" target="_blank">(.*?)</a>&nbsp;`);
        auto actorsMatchs = matchAll(dom.getInner(infosNodes[0]), rexActors);
        string actors = "";
        if (actorsMatchs.empty)
        {
            actors = "未知";
        }
        else
        {
            foreach (m; actorsMatchs)
            {
                actors ~= (m[1] ~ " ");
            }
        }
        // writeln(actors);

        auto rexDirector = ctRegex!(`<a href=".*?" target="_blank">(.*?)</a>&nbsp;`);
        auto directorMatchs = matchAll(dom.getInner(infosNodes[1]), rexDirector);
        string directors = "";
        if (directorMatchs.empty)
        {
            directors = "未知";
        }
        else
        {
            foreach (m; directorMatchs)
            {
                directors ~= (m[1] ~ " ");
            }
        }
        // writeln(directors);

        auto rexCate = ctRegex!(`类型：</span>(.*?)<span`);
        auto cateMatch = matchFirst(dom.getInner(infosNodes[2]), rexCate);
        string cate = "";
        if (cateMatch.empty)
        {
            cate = "未知";
        }
        cate = cateMatch[1];
        // writeln(cate);

        auto rexRegion = ctRegex!(`地区：</span>(.*?)<span`);
        auto regionMatch = matchFirst(dom.getInner(infosNodes[2]), rexRegion);
        string region = "";
        if (regionMatch.empty)
        {
            region = "未知";
        }
        region = regionMatch[1];
        // writeln(region);

        auto rexYear = ctRegex!(`年份：</span>(.*?)$`);
        // auto rexYear = ctRegex!(`年份：</span>(\d+)`);
        auto yearMatch = matchFirst(dom.getInner(infosNodes[2]), rexYear);
        uint year;
        if (yearMatch.empty)
        {
            year = 0;
        }
        year = to!uint(yearMatch[1]);
        // writeln(year);

        auto rexIntro = ctRegex!(`简介：</span><span class="detail-sketch">(.*?)</span>`);
        auto introMatch = matchFirst(dom.getInner(infosNodes[4]), rexIntro);
        string intro = "";
        if (introMatch.empty)
        {
            intro = "未知";
        }
        intro = introMatch[1];
        // writeln(intro);

        auto imgAttrs = dom.filterDom("img{class:lazyload}")[0].getAttributes();
        string img = "";
        if (imgAttrs.length == 0)
        {
            img = "";
        }
        else
        {
            img = imgAttrs[2].values[0];
        }

        animation = new AnimationDtoFromCreate(animationId, name, url, cate, region, year, actors, directors, intro, img, "暂无");

        Node[] linkNodes = dom.filterDom("ul{class:stui-content__playlist}");
        auto rexlinkInfos = ctRegex!(`<a href="(.*?)">(.*?)</a>`);
        auto linkInfosMatchs = matchAll(dom.getInner(linkNodes[0]), rexlinkInfos);
        if (linkInfosMatchs.empty)
        {
            return tuple(animation, animationLinkList);
        }
        foreach (link; linkInfosMatchs)
        {
            animationLinkList ~= new AnimationVlinkDtoFromCreate(
                animationId,
                link[2],
                ("https://www.hmmgy.com" ~ link[1]));
        }

        return tuple(animation, animationLinkList);
    }

}
